#ifndef __CONTROLBOARD_CONTROLLER__
#define __CONTROLBOARD_CONTROLLER__

#include <QObject>
#include <QThread>
#include <QSerialPort>
#include <QMutex>

#define CB_FAN_CMD						0x20
#define CB_FAN_INQUIRE_CMD				0x21
#define CB_GATE_CMD						0x30
#define CB_GATE_INQUIRE_CMD				0x31

#define CB_FAN_INFO_RESPONSE			0x70
#define CB_GATE_INFO_RESPONSE			0x80

#define CB_FAN_ON_STATUS				0x01
#define CB_FAN_OFF_STATUS				0x01

#define CB_GATE_CLOSE_STATUS			0x00
#define CB_GATE_MOVING_STATUS			0x01
#define CB_GATE_OPEN_STATUS				0x02

class Coordinator;
class QTimer;

class ControlBoard_Worker : public QObject
{
	Q_OBJECT

public:

	struct SerialConfig {
		QString port;
		uint32_t baud = QSerialPort::Baud115200;
		QSerialPort::DataBits data_bits = QSerialPort::Data8;
		QSerialPort::StopBits stop_bits = QSerialPort::OneStop;
		QSerialPort::Parity parity = QSerialPort::NoParity;
	};
	typedef struct SerialConfig SerialConfig;

    ControlBoard_Worker(QObject *parent = nullptr);
    ~ControlBoard_Worker();

    void setSerialParam(SerialConfig param);

    bool gate_opened() { return m_gate_opened; };

signals:

	void status(bool status);

public slots:

	void start_work();
	void stop_work();

	void open_store_gate();
	void close_store_gate();

	void turn_on_fans();
	void turn_off_fans();

	void takeout_paper();
	void prepare_store();
	void store_paper();

private slots:

	void process_cmd_resp();
	void check_gate();

private:

	void transfer_cmd(QByteArray cmd);

    QByteArray rcsv_analyze(QByteArray &raw_data);
	void parse_msg(QByteArray msg);

	QByteArray parse_response(QByteArray resp);

private:

	QMutex m_mutex;

	SerialConfig m_param;
	QSerialPort *m_port;
	QTimer *m_worker_timer;
	QTimer *m_gate_check_timer;

	bool m_fan_working;
	bool m_gate_opened;

	QList<QByteArray> m_cmd_list;
	QByteArray m_response;
	uint16_t m_cmd_status;
	uint16_t m_wait_time;
};

class CntlBoardController : public QObject
{
	Q_OBJECT

public:

    CntlBoardController(QObject *parent = nullptr);
    ~CntlBoardController();

    ControlBoard_Worker *getWorker() {
        return m_worker;
    }

signals:

	void start();
	void stop();

private:

	QThread m_worker_thread;
	ControlBoard_Worker *m_worker;

    Coordinator *m_coordinator;
};

#endif
